/* /////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2004-2008 Intel Corporation. All Rights Reserved.
//
//
//          VC-1 (VC1) decoder, MB Layer common for simple\main profiles
//
*/
#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)

#include "umc_vc1_dec_seq.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_common_defs.h"
#include "umc_vc1_common_blk_order_tbl.h"

static const Ipp8u esbp_lut[] = {1,2,2,2,4,4,4,8};

inline static bool GetEdgeValue(Ipp32s Edge, Ipp32s& Current)
{
    if (Current <= 0)
    {
        Current = 0;
        return true;
    }
    else
    {
        if (Current < Edge)
            return false;
        else
        {
            Current = Edge - 1;
            return true;
        }
    }
}

#ifdef _OWN_FUNCTION

#define CLIP(x) (!(x&~255)?x:(x<0?0:255))

static const int BicubicFilterParams[4][4] =
{
    {-4,    53,     18,     -3}, // 1/4
    {-1,    9,      9,      -1}, // 1/2
    {-3,    18,     53,     -4}  // 3/4
};

static const char BicubicVertFilterShift[4][3] =
{
    {6, 4, 6},
    {5, 3, 5},
    {3, 1, 3},
    {5, 3, 5}
};

static const char BicubicHorizFilterShift[3][4] =
{
    {6, 7, 7, 7},
    {4, 7, 7, 7},
    {6, 7, 7, 7}
};

typedef IppStatus (*ippiBicubicInterpolate)     (const Ipp8u* pSrc,
                                                 Ipp32s srcStep,
                                                 Ipp8u *pDst,
                                                 Ipp32s dstStep,
                                                 Ipp32s dx,
                                                 Ipp32s dy,
                                                 Ipp32s roundControl);


static IppStatus ippiInterpolate16x16QPBicubicIC_VC1_8u_C1R (const Ipp8u* pSrc,
                                                             Ipp32s srcStep,
                                                             Ipp8u *pDst,
                                                             Ipp32s dstStep,
                                                             Ipp32s dx,
                                                             Ipp32s dy,
                                                             Ipp32s roundControl)
{
    IppStatus ret = ippStsNoErr;
    unsigned choose_int = ( (1==(0==(dx))) |(((1==(0 == (dy))) << 1)));

    short TempBlock[(17 + 3) * 17];
    int i, j;
    int PBPL          = 17 + 3;
    int R             = roundControl;

    short         *pDst16 = TempBlock + 1;
    short         *pSource16 = TempBlock + 1;
    int Pixel;
    int Fy0, Fy1, Fy2, Fy3;
    int Fx0, Fx1, Fx2, Fx3;



    const int (*FP) = BicubicFilterParams[(dy) - 1];
    int Abs, Shift;
    Fy0          = FP[0];
    Fy1          = FP[1];
    Fy2          = FP[2];
    Fy3          = FP[3];
    FP = BicubicFilterParams[dx - 1];
    Fx0          = FP[0];
    Fx1          = FP[1];
    Fx2          = FP[2];
    Fx3          = FP[3];


#ifdef INTERDEBUG
    printf("New Source Block \n");
    for(j = -1; j < 18; j++)
    {
        for(i = -1; i < 18; i++)
        {
            printf(" %d ",pSrc[i  + j*srcStep]);
        }
        printf(" \n");
    }
#endif



    switch(choose_int)
    {
    case 0:

        Shift           = BicubicVertFilterShift[(dx)][(dy) - 1];
        Abs             = 1 << (Shift - 1);

        /* vertical filter */
        for(j = 0; j < 16; j++)
        {
            for(i = -1; i < 3; i++)
            {
                Pixel = ((pSrc[i - srcStep] * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]  * Fy2 +
                    pSrc[i + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);

                pDst16[i] = (short)Pixel;

            }
            for(;i < 16+2; i++)
            {
                Pixel = ((pSrc[i - srcStep]  * Fy0 +
                    pSrc[i]              * Fy1 +
                    pSrc[i  + srcStep]  * Fy2 +
                    pSrc[i  + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);
                pDst16[i] = (short)Pixel;
                pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                    pDst16[i-3] * Fx1 +
                    pDst16[i-2] * Fx2 +
                    pDst16[i-1] * Fx3 + 64 - R) >> 7);
            }
            pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                pDst16[i-3] * Fx1 +
                pDst16[i-2] * Fx2 +
                pDst16[i-1] * Fx3 + 64 - R) >> 7);
            pDst   += dstStep;
            pSrc   += srcStep;
            pDst16 += PBPL;
        }

        break;
    case 1:

        Shift           = BicubicVertFilterShift[0][(dy) - 1];
        Abs             = 1 << (Shift - 1);


        for(j = 0; j < 16; j++)
        {
            for(i = 0; i < 16; i++)
            {

                pDst[i] = CLIP((pSrc[i - srcStep]   * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]   * Fy2 +
                    pSrc[i + 2*srcStep] * Fy3 +
                    Abs - 1 + R) >> Shift);
            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;

    case 2:
        Shift           = BicubicHorizFilterShift[(dx) - 1][0];
        Abs             = 1 << (Shift - 1);

        for(j = 0; j < 16; j++)
        {
            for(i = 0; i < 16; i++)
            {
                pDst[i] = CLIP((pSrc[i-1]   * Fx0 +
                    pSrc[i]     * Fx1 +
                    pSrc[i+1]   * Fx2 +
                    pSrc[i + 2] * Fx3 +
                    Abs - R) >> Shift);
            }
            pSrc += srcStep;
            pDst += dstStep;
            //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("\n") );
        }
        break;
    case 3:
        for(j = 0; j < 16; j++)
        {
            for(i = 0; i < 16; i++)
            {
                pDst[i] = pSrc[i];

            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;
    default:
        break;
    }
    return ret;
}

static IppStatus ippiInterpolate16x8QPBicubicIC_VC1_8u_C1R (const Ipp8u* pSrc,
                                                            Ipp32s srcStep,
                                                            Ipp8u *pDst,
                                                            Ipp32s dstStep,
                                                            Ipp32s dx,
                                                            Ipp32s dy,
                                                            Ipp32s roundControl)
{
    IppStatus ret = ippStsNoErr;
    unsigned choose_int = ( (1==(0==(dx))) |(((1==(0 == (dy))) << 1)));
    static unsigned inter_flag = 0;


    short TempBlock[(17 + 3) * 17];
    int i, j;
    int PBPL          = 17 + 3;
    int R             = roundControl;

    short         *pDst16 = TempBlock + 1;
    short         *pSource16 = TempBlock + 1;
    int Pixel;
    int Fy0, Fy1, Fy2, Fy3;
    int Fx0, Fx1, Fx2, Fx3;
    const int (*FP) = BicubicFilterParams[(dy) - 1];
    int Abs, Shift;
    Fy0          = FP[0];
    Fy1          = FP[1];
    Fy2          = FP[2];
    Fy3          = FP[3];

    FP = BicubicFilterParams[dx - 1];
    Fx0          =  FP[0];
    Fx1          =  FP[1];
    Fx2          =  FP[2];
    Fx3          =  FP[3];

#ifdef INTERDEBUG
    printf("New Source Block \n");
    for(j = -1; j < 10; j++)
    {
        for(i = -1; i < 18; i++)
        {
            printf(" %d ",pSrc[i  + j*srcStep]);
        }
        printf(" \n");
    }
#endif


    switch(choose_int)
    {
    case 0:

        Shift           = BicubicVertFilterShift[(dx)][(dy) - 1];
        Abs             = 1 << (Shift - 1);

        /* vertical filter */

        for(j = 0; j < 8; j++)
        {
            for(i = -1; i < 3; i++)
            {
                Pixel = ((pSrc[i - srcStep] * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]  * Fy2 +
                    pSrc[i + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);

                pDst16[i] = (short)Pixel;

            }
            for(;i < 16+2; i++)
            {
                Pixel = ((pSrc[i - srcStep]  * Fy0 +
                    pSrc[i]              * Fy1 +
                    pSrc[i  + srcStep]  * Fy2 +
                    pSrc[i  + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);
                pDst16[i] = (short)Pixel;
                pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                    pDst16[i-3] * Fx1 +
                    pDst16[i-2] * Fx2 +
                    pDst16[i-1] * Fx3 + 64 - R) >> 7);
            }
            pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                pDst16[i-3] * Fx1 +
                pDst16[i-2] * Fx2 +
                pDst16[i-1] * Fx3 + 64 - R) >> 7);
            pDst   += dstStep;
            pSrc   += srcStep;
            pDst16 += PBPL;
        }
        break;
    case 1:

        Shift           = BicubicVertFilterShift[0][(dy) - 1];
        Abs             = 1 << (Shift - 1);


        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 16; i++)
            {

                pDst[i] = CLIP((pSrc[i - srcStep]   * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]   * Fy2 +
                    pSrc[i + 2*srcStep] * Fy3 +
                    Abs - 1 + R) >> Shift);
            }
            pSrc += srcStep;
            pDst += dstStep;
        }

        break;
    case 2:
        Shift           = BicubicHorizFilterShift[(dx) - 1][0];
        Abs             = 1 << (Shift - 1);


        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 16; i++)
            {
                pDst[i] = CLIP((pSrc[i-1]   * Fx0 +
                    pSrc[i]     * Fx1 +
                    pSrc[i+1]   * Fx2 +
                    pSrc[i + 2] * Fx3 +
                    Abs - R) >> Shift);
            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;

    case 3:

        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 16; i++)
            {
                //pPixels[I] = IC_SCAN(pSource[I], IC_matrix);
                pDst[i] = pSrc[i];

            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;
    default:
        break;
    }
    return ret;
}

static IppStatus ippiInterpolate8x8QPBicubicIC_VC1_8u_C1R (const Ipp8u* pSrc,
                                                           Ipp32s srcStep,
                                                           Ipp8u *pDst,
                                                           Ipp32s dstStep,
                                                           Ipp32s dx,
                                                           Ipp32s dy,
                                                           Ipp32s roundControl)
{
    IppStatus ret = ippStsNoErr;

    unsigned choose_int = ( (1==(0==(dx))) |(((1==(0 == (dy))) << 1)));
    short TempBlock[(17 + 3) * 17];
    int i, j;
    int PBPL          = 17 + 3;
    int R             = roundControl;

    short         *pDst16 = TempBlock + 1;
    short         *pSource16 = TempBlock + 1;
    int Pixel;
    int Fy0, Fy1, Fy2, Fy3;
    int Fx0, Fx1, Fx2, Fx3;
    const int (*FP) = BicubicFilterParams[(dy) - 1];
    int Abs, Shift;
    Fy0          = FP[0];
    Fy1          = FP[1];
    Fy2          = FP[2];
    Fy3          = FP[3];

    FP = BicubicFilterParams[dx - 1];
    Fx0          = FP[0];
    Fx1          = FP[1];
    Fx2          = FP[2];
    Fx3          = FP[3];


#ifdef INTERDEBUG
    printf("New Source Block \n");
    for(j = -1; j < 10; j++)
    {
        for(i = -1; i < 10; i++)
        {
            printf(" %d ",pSrc[i  + j*srcStep]);
        }
        printf(" \n");
    }
#endif

    switch(choose_int)
    {
    case 0:

        Shift           = BicubicVertFilterShift[(dx)][(dy) - 1];
        Abs             = 1 << (Shift - 1);
        FP = BicubicFilterParams[dx - 1];
        Fx0          = (int)FP[0];
        Fx1          = (int)FP[1];
        Fx2          = (int)FP[2];
        Fx3          = (int)FP[3];

        /* vertical filter */

        for(j = 0; j < 8; j++)
        {
            for(i = -1; i < 3; i++)
            {
                Pixel = ((pSrc[i - srcStep] * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]  * Fy2 +
                    pSrc[i + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);

                pDst16[i] = (short)Pixel;

            }
            for(;i < 8+2; i++)
            {
                Pixel = ((pSrc[i - srcStep]  * Fy0 +
                    pSrc[i]              * Fy1 +
                    pSrc[i  + srcStep]  * Fy2 +
                    pSrc[i  + 2*srcStep]* Fy3 +
                    Abs - 1 + R) >> Shift);
                pDst16[i] = (short)Pixel;
                pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                    pDst16[i-3] * Fx1 +
                    pDst16[i-2] * Fx2 +
                    pDst16[i-1] * Fx3 + 64 - R) >> 7);
            }
            pDst[i-3] = CLIP((pDst16[i-4] * Fx0 +
                pDst16[i-3] * Fx1 +
                pDst16[i-2] * Fx2 +
                pDst16[i-1] * Fx3 + 64 - R) >> 7);
            pDst   += dstStep;
            pSrc   += srcStep;
            pDst16 += PBPL;
        }
        break;
    case 1:

        Shift           = BicubicVertFilterShift[0][(dy) - 1];
        Abs             = 1 << (Shift - 1);


        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 8; i++)
            {
                pDst[i] = CLIP((pSrc[i - srcStep]   * Fy0 +
                    pSrc[i]             * Fy1 +
                    pSrc[i + srcStep]   * Fy2 +
                    pSrc[i + 2*srcStep] * Fy3 +
                    Abs - 1 + R) >> Shift);
                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("Source\n"));
                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("%d  \n"), pSrc[i - srcStep] );
                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("%d  \n"), pSrc[i] );
                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("%d  \n"), pSrc[i + srcStep] );
                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("%d  \n"), pSrc[i + 2*srcStep] );

                //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("%d  \n"), pDst[i] );
            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;
    case 2:
        Shift           = BicubicHorizFilterShift[(dx) - 1][0];
        Abs             = 1 << (Shift - 1);

        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 8; i++)
            {
                pDst[i] = CLIP((pSrc[i-1]   * Fx0 +
                    pSrc[i]     * Fx1 +
                    pSrc[i+1]   * Fx2 +
                    pSrc[i + 2] * Fx3 +
                    Abs - R) >> Shift);
            }
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;
    case 3:

        for(j = 0; j < 8; j++)
        {
            for(i = 0; i < 8; i++)
            {
                //pPixels[I] = IC_SCAN(pSource[I], IC_matrix);
                pDst[i] = pSrc[i];

            }
            //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_PRED,VM_STRING("\n") );
            pSrc += srcStep;
            pDst += dstStep;
        }
        break;
    default:
        break;
    }
    return ret;
}


static const ippiBicubicInterpolate ippiBicubicInterpolate_table[] = {
    (ippiBicubicInterpolate)(ippiInterpolate8x8QPBicubicIC_VC1_8u_C1R),
    (ippiBicubicInterpolate)(ippiInterpolate16x8QPBicubicIC_VC1_8u_C1R),
    (ippiBicubicInterpolate)(ippiInterpolate16x16QPBicubicIC_VC1_8u_C1R),
};


IppStatus _own_ippiInterpolateQPBicubicIC_VC1_8u_C1R   (_IppVCInterpolate_8u* inter_struct)
{
    IppStatus ret = ippStsNoErr;
    int pinterp = (inter_struct->roiSize.width >> 4) + (inter_struct->roiSize.height >> 4);
    ret= ippiBicubicInterpolate_table[pinterp](inter_struct->pSrc,
        inter_struct->srcStep,
        inter_struct->pDst,
        inter_struct->dstStep,
        inter_struct->dx,
        inter_struct->dy,
        inter_struct->roundControl);
    return ret;
}
#endif
void DecodeTransformInfo(VC1Context* pContext)
{
    Ipp32u i;
    if(pContext->m_seqLayerHeader->VSTRANSFORM)
    {
        if (pContext->m_picLayerHeader->TTMBF == 0 &&
            (pContext->m_pCurrMB->mbType != VC1_MB_INTRA) )
        {
            GetTTMB(pContext);
        }
        else
        {
            if (!pContext->m_pCurrMB->mbType == VC1_MB_INTRA)
            {
                for (i=0;i<VC1_NUM_OF_BLOCKS;i++)
                {
                    if (!VC1_IS_BLKINTRA(pContext->m_pCurrMB->m_pBlocks[i].blkType))
                        pContext->m_pCurrMB->m_pBlocks[i].blkType = (Ipp8u)pContext->m_picLayerHeader->TTFRM;
                }
            }
            else
                for (i=0;i<VC1_NUM_OF_BLOCKS;i++)
                    pContext->m_pCurrMB->m_pBlocks[i].blkType = VC1_BLK_INTRA;

        }
    }
    //else
    //{
    //    for (i=0;i<VC1_NUM_OF_BLOCKS;i++)
    //        pContext->m_pCurrMB->m_pBlocks[i].blkType = (Ipp8u)pContext->m_picLayerHeader->TTFRM;
    //}
}

VC1Status GetTTMB(VC1Context* pContext)
{
    IppStatus ret;
    VC1MB *pMB = pContext->m_pCurrMB;
    Ipp32s eSBP;
    Ipp8u Count, Limit, FirstBlock = 0;

    while ( (FirstBlock <  VC1_NUM_OF_BLOCKS)             &&
        ((0 == ((1 << (5-FirstBlock)) & pMB->m_cbpBits)) ||
        (pMB->m_pBlocks[FirstBlock].blkType == VC1_BLK_INTRA) )
        )
    {
        FirstBlock++;
    }

    if(FirstBlock == VC1_NUM_OF_BLOCKS)
    {
        return VC1_OK;
    }

    ret = ippiDecodeHuffmanOne_1u32s(  &pContext->m_bitstream.pBitstream,
        &pContext->m_bitstream.bitOffset,
        &eSBP,
        pContext->m_picLayerHeader->m_pCurrTTMBtbl);
    VM_ASSERT(ret == ippStsNoErr);

    //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_TT,VM_STRING("TTMB = %d\n"), eSBP);

    Limit = VC1_NUM_OF_BLOCKS;

    if(eSBP < VC1_SBP_8X8_MB)
    {
        Limit = FirstBlock + 1;
    }
    else
    {
        eSBP -= VC1_SBP_8X8_MB;
    }

    //printf("eSBP = %d\n",eSBP);
    //printf("offset = %d\n", pContext->m_bitOffset);

    pContext->m_pSingleMB->m_ubNumFirstCodedBlk = FirstBlock;

    pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = 0;

    switch(eSBP)
    {
    case VC1_SBP_8X8_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_0;
        break;

    case VC1_SBP_8X4_BOTTOM_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_1;
        break;

    case VC1_SBP_8X4_TOP_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_0;
        break;

    case VC1_SBP_8X4_BOTH_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_0|VC1_SBP_1;
        break;

    case VC1_SBP_4X8_RIGHT_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_1;
        break;

    case VC1_SBP_4X8_LEFT_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_0;
        break;

    case VC1_SBP_4X8_BOTH_BLK:
        pContext->m_pSingleMB->m_pSingleBlock[FirstBlock].numCoef = VC1_SBP_0|VC1_SBP_1;
        break;

    case VC1_SBP_4X4_BLK:
        //nothing to do
        break;

    default:
        return VC1_FAIL;
    }

    for(Count = FirstBlock; Count < Limit; Count++)
    {
        if(!(pMB->m_pBlocks[Count].blkType == VC1_BLK_INTRA))
        {
            VM_ASSERT(eSBP<8);
            pMB->m_pBlocks[Count].blkType = VC1_LUT_SET(eSBP,esbp_lut);
        }
    }

    for( ; Count < VC1_NUM_OF_BLOCKS; Count++)
    {
        if(!(pMB->m_pBlocks[Count].blkType == VC1_BLK_INTRA))
        {
            pMB->m_pBlocks[Count].blkType = VC1_BLK_INTER;
        }
    }

    return VC1_OK;
}
IppStatus ippiICInterpolateQPBicubicBlock_VC1_8u_P1R(const IppVCInterpolateBlock_8u* interpolateInfo,
                                                     const Ipp8u*                   pLUTTop,
                                                     const Ipp8u*                   pLUTBottom,
                                                     Ipp32u                          OppositePadding,
                                                     Ipp32u                          fieldPrediction,
                                                     Ipp32u                          RoundControl,
                                                     Ipp32u                          isPredBottom)

{
    Ipp8u    temp_block [19*19]          = {0};
    IppiSize temp_block_size             = {interpolateInfo->sizeBlock.width + 3, interpolateInfo->sizeBlock.height + 3};
    Ipp32s   temp_block_step             = 19;
    Ipp8u*   p_temp_block_data_pointer   = temp_block;
    Ipp8u    shift = (fieldPrediction)? 1:0;

    IppiPoint position = {interpolateInfo->pointBlockPos.x,
        interpolateInfo->pointBlockPos.y};

    Ipp32u step = 0;

    Ipp32s TopFieldPOffsetTP = 0;
    Ipp32s BottomFieldPOffsetTP = 1;

    Ipp32s TopFieldPOffsetBP = 2;
    Ipp32s BottomFieldPOffsetBP = 1;


    Ipp32u SCoef = (fieldPrediction)?1:0; // in case of interlace fields we should use half of frame height


    // minimal distance from current point for interpolation.
    Ipp32s left = 1;
    Ipp32s right = interpolateInfo->sizeFrame.width - (interpolateInfo->sizeBlock.width + 2);
    Ipp32s top = 1; //<< shift;

    Ipp32s bottom = (interpolateInfo->sizeFrame.height >> SCoef)  - (interpolateInfo->sizeBlock.height + 2);
    Ipp32s   paddingLeft    = (position.x < left) ?  left  - position.x: 0;
    Ipp32s   paddingRight   = (position.x > right)?  position.x - right: 0;
    Ipp32s   paddingTop     = (position.y < top)?    (top - position.y): 0;
    Ipp32s   paddingBottom  = (position.y > bottom)? (position.y - bottom): 0;
    Ipp32s   RefBlockStep = interpolateInfo->srcStep << shift;
    const Ipp8u*   pRefBlock =    interpolateInfo->pSrc[0] + (position.x + paddingLeft - 1) +
                            (position.y + paddingTop  - 1)* RefBlockStep;
    const Ipp8u* pLUT[2];

    if (isPredBottom)
    {
        pLUT[0] = (fieldPrediction)?pLUTBottom:pLUTTop;
        pLUT[1] = pLUTBottom;
    }
    else
    {
        pLUT[1] = (fieldPrediction)?pLUTTop:pLUTBottom;
        pLUT[0] = pLUTTop;
    }

    if ((position.y + paddingTop  - 1) % 2)
    {
        const Ipp8u* pTemp;
        pTemp = pLUT[0];
        pLUT[0] = pLUT[1];
        pLUT[1] = pTemp;
    }

    if (OppositePadding == 0)
    {
        isPredBottom = 0;
    }



    temp_block_size.width  -=  (paddingLeft + paddingRight);
    temp_block_size.height -=  (paddingTop + paddingBottom);

    // all block out of plane
    if (temp_block_size.height <= 0)
    {
        const Ipp8u* pTemp;
        temp_block_size.height = 0;
        if (paddingTop != 0)
        {
            // see paddingBottom
            paddingTop = (interpolateInfo->sizeBlock.height + 3);
            if ((OppositePadding)&(position.y % 2 != 0))
            {
                TopFieldPOffsetTP = 1;
                BottomFieldPOffsetTP = 0;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
        }
        if (paddingBottom != 0)
        {
            paddingBottom = (interpolateInfo->sizeBlock.height + 3);
            if ((OppositePadding)&(position.y % 2 == 0))
            {
                TopFieldPOffsetBP = 1;
                BottomFieldPOffsetBP = 2;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
        }

    }
    if (temp_block_size.width <= 0)
    {
        Ipp32s FieldPOffset[2] = {0,0};
        Ipp32s posy;



        if ((OppositePadding)&&(!fieldPrediction))
        {
            if (paddingTop)
            {
                if ((position.y - 1) % 2)
                {
                    FieldPOffset[0] = 1;
                    FieldPOffset[1] = 0;
                }
                else
                {
                    FieldPOffset[0] = 0;
                    FieldPOffset[1] = 1;
                }

            }
            else if (paddingBottom)
            {
                if ((position.y - 1) % 2)
                {
                    FieldPOffset[0] = 0;
                    FieldPOffset[1] = -1;
                }
                else
                {
                    FieldPOffset[0] = -1;
                    FieldPOffset[1] = 0;
                }
            }

        }

        // Compare with paddingRight case !!!!
        if (paddingLeft)
        {
            for (int nfield = 0; nfield < 2; nfield ++)
            {
                for (int i = nfield; i < interpolateInfo->sizeBlock.height + 3; i+=2)
                {
                    posy = position.y + i - 1;
                    if (GetEdgeValue(interpolateInfo->sizeFrame.height >> SCoef, posy))
                        posy += FieldPOffset[nfield];

                    temp_block[i*temp_block_step + interpolateInfo->sizeBlock.width + 3] = (pLUT [nfield])?
                                pLUT [nfield][interpolateInfo->pSrc[0][RefBlockStep * posy]]:
                                interpolateInfo->pSrc[0][RefBlockStep * posy];
                }

            }
            paddingLeft = (paddingLeft != 0)?(interpolateInfo->sizeBlock.width + 3):paddingLeft;
        }
        if (paddingRight)
        {
            for (int nfield = 0; nfield < 2; nfield ++)
            {
                for (int i = nfield; i < interpolateInfo->sizeBlock.height + 3; i+=2)
                {
                    posy = position.y + i - 1;
                    if (GetEdgeValue(interpolateInfo->sizeFrame.height >> SCoef, posy))
                        posy += FieldPOffset[nfield];

                    temp_block[i*temp_block_step] = (pLUT [nfield])?
                    pLUT [nfield][interpolateInfo->pSrc[0][RefBlockStep * posy + interpolateInfo->sizeFrame.width - 1]]:
                                  interpolateInfo->pSrc[0][RefBlockStep * posy + interpolateInfo->sizeFrame.width - 1];
                }

            }
            paddingRight = (paddingRight != 0)?(interpolateInfo->sizeBlock.width + 2):paddingRight;
        }
    }

    // prepare dst
    p_temp_block_data_pointer += paddingTop * temp_block_step + paddingLeft;
    {
         // copy block
        for (int nfield = 0; nfield < 2; nfield ++)
        {
            for (int i = nfield; i < temp_block_size.height; i+=2)
            {
                for (int j = 0; j < temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUT [nfield])?
                        pLUT[nfield][pRefBlock[i*RefBlockStep + j]]:
                    pRefBlock[i*RefBlockStep + j];
                }
            }
        }
    }
    if ((!OppositePadding)||(fieldPrediction))
    {
        if (!OppositePadding)
        {
            // interlace padding. Field prediction
            // top
            for (int i = -paddingTop; i < 0; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {

                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUT[0])?
                        pLUT[0][interpolateInfo->pSrc[0][position.x + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]; //!!! - isPredBottom*interpolateInfo->srcStep]; ///in case of isPredBottom we should use th second string
                }
            }
            // bottom
            for (int i = 0; i < paddingBottom; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[1])?
                        pLUT[1][interpolateInfo->pSrc[0][position.x + ((interpolateInfo->sizeFrame.height >> SCoef) - 1)*RefBlockStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + ((interpolateInfo->sizeFrame.height >> SCoef) - 1)*RefBlockStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep];
                }
            }
        }
        else
        {
            // progressive padding. Field prediction
            // top
            for (int i = -paddingTop; i < 0; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {

                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUTTop)?
                        pLUTTop[interpolateInfo->pSrc[0][position.x + paddingLeft +j -left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft +j -left - isPredBottom*interpolateInfo->srcStep];
                }
            }
            // bottom
            for (int i = 0; i < paddingBottom; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUTBottom)?
                        pLUTBottom[interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - 1)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - 1)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep];
                }
            }
        }
    }
    else
    {
        // Field  padding. Progressive prediction
        if (paddingTop)
        {
            // top
            for (int i = 2; i <= paddingTop; i +=2)
            {
                for (int j = 0; j < temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[-i*temp_block_step + j] = (pLUT[0])?
                        pLUT[0][interpolateInfo->pSrc[0][position.x + paddingLeft + j +TopFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft + j + TopFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep];
                }
            }
            for (int i = 1; i <= paddingTop; i +=2)
            {
                for (int j = 0; j < temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[-i*temp_block_step + j] = (pLUT[1])?
                        pLUT[1][interpolateInfo->pSrc[0][position.x + paddingLeft +j + BottomFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft +j + BottomFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep];
                }
            }
        }
        if (paddingBottom)
        {
            if (paddingBottom % 2)
            {
                const Ipp8u* pTemp;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
            // bottom
            for (int i = 0; i < paddingBottom; i +=2)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[1])?
                        pLUT[1][interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - TopFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j- left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - TopFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j- left - isPredBottom*RefBlockStep];
                }
            }
            for (int i = 1; i < paddingBottom; i +=2)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[0])?
                        pLUT[0][interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - BottomFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - BottomFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*RefBlockStep];
                }
            }
        }
    }

    for (int i = 0; i < paddingLeft; i ++)
    {
        for (int j = 0; j < interpolateInfo->sizeBlock.height + 3; j++)
        {
            temp_block [i+ j*temp_block_step ] = temp_block[paddingLeft+ j*temp_block_step];
        }
    }
    for (int i = 1; i <=paddingRight; i ++)
    {
        for (int j = 0; j < interpolateInfo->sizeBlock.height + 3; j++)
        {
            temp_block [interpolateInfo->sizeBlock.width + 3 - i + j*temp_block_step + step] =
                temp_block[ interpolateInfo->sizeBlock.width + 3 - paddingRight  - 1 + j*temp_block_step + step];
        }
    }

    IppVCInterpolate_8u inter_struct;
    inter_struct.srcStep = 19;
    inter_struct.pSrc = temp_block + 1 + inter_struct.srcStep;
    inter_struct.pDst = interpolateInfo->pDst[0];
    inter_struct.dstStep = interpolateInfo->dstStep;
    inter_struct.dx = interpolateInfo->pointVector.x;
    inter_struct.dy = interpolateInfo->pointVector.y;
    inter_struct.roundControl = RoundControl;
    inter_struct.roiSize.width = interpolateInfo->sizeBlock.width;
    inter_struct.roiSize.height = interpolateInfo->sizeBlock.height;

    return _own_ippiInterpolateQPBicubicIC_VC1_8u_C1R(&inter_struct);
}

IppStatus ippiICInterpolateQPBilinearBlock_VC1_8u_P1R(const IppVCInterpolateBlock_8u* interpolateInfo,
                                                      const   Ipp8u*                 pLUTTop,
                                                      const   Ipp8u*                 pLUTBottom,
                                                      Ipp32u                          OppositePadding,
                                                      Ipp32u                          fieldPrediction,
                                                      Ipp32u                          RoundControl,
                                                      Ipp32u                          isPredBottom)

{
    Ipp8u    temp_block [19*19]          = {0};
    IppiSize temp_block_size             = {interpolateInfo->sizeBlock.width + 3, interpolateInfo->sizeBlock.height + 3};
    Ipp32s   temp_block_step             = 19;
    Ipp8u*   p_temp_block_data_pointer   = temp_block;
    Ipp8u    shift = (fieldPrediction)? 1:0;

    IppiPoint position = {interpolateInfo->pointBlockPos.x,
        interpolateInfo->pointBlockPos.y};

    Ipp32u step = 0;

    Ipp32s TopFieldPOffsetTP = 0;
    Ipp32s BottomFieldPOffsetTP = 1;

    Ipp32s TopFieldPOffsetBP = 2;
    Ipp32s BottomFieldPOffsetBP = 1;


    Ipp32u SCoef = (fieldPrediction)?1:0; // in case of interlace fields we should use half of frame height


    // minimal distance from current point for interpolation.
    Ipp32s left = 1;
    Ipp32s right = interpolateInfo->sizeFrame.width - (interpolateInfo->sizeBlock.width + 2);
    Ipp32s top = 1; //<< shift;

    Ipp32s bottom = (interpolateInfo->sizeFrame.height >> SCoef)  - (interpolateInfo->sizeBlock.height + 2);
    Ipp32s   paddingLeft    = (position.x < left) ?  left  - position.x: 0;
    Ipp32s   paddingRight   = (position.x > right)?  position.x - right: 0;
    Ipp32s   paddingTop     = (position.y < top)?    (top - position.y): 0;
    Ipp32s   paddingBottom  = (position.y > bottom)? (position.y - bottom): 0;
    Ipp32s   RefBlockStep = interpolateInfo->srcStep << shift;
    const Ipp8u*   pRefBlock =    interpolateInfo->pSrc[0] + (position.x + paddingLeft - 1) +
                            (position.y + paddingTop  - 1)* RefBlockStep;
    const Ipp8u* pLUT[2];
    if (isPredBottom)
    {
        pLUT[0] = (fieldPrediction)?pLUTBottom:pLUTTop;
        pLUT[1] = pLUTBottom;
    }
    else
    {
        pLUT[1] = (fieldPrediction)?pLUTTop:pLUTBottom;
        pLUT[0] = pLUTTop;
    }

    if ((position.y + paddingTop - 1) % 2)
    {
        const Ipp8u* pTemp;
        pTemp = pLUT[0];
        pLUT[0] = pLUT[1];
        pLUT[1] = pTemp;
    }

    if (OppositePadding == 0)
    {
        isPredBottom = 0;
    }


    temp_block_size.width  -=  (paddingLeft + paddingRight);
    temp_block_size.height -=  (paddingTop + paddingBottom);

    // all block out of plane
    if (temp_block_size.height <= 0)
    {
        const Ipp8u* pTemp;
        temp_block_size.height = 0;
        if (paddingTop != 0)
        {
            // see paddingBottom
            paddingTop = (interpolateInfo->sizeBlock.height + 3);
            if ((OppositePadding)&(position.y % 2 != 0))
            {
                TopFieldPOffsetTP = 1;
                BottomFieldPOffsetTP = 0;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
        }
        if (paddingBottom != 0)
        {
            paddingBottom = (interpolateInfo->sizeBlock.height + 3);
            if ((OppositePadding)&(position.y % 2 == 0))
            {
                TopFieldPOffsetBP = 1;
                BottomFieldPOffsetBP = 2;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
        }

    }

    if (temp_block_size.width <= 0)
    {
        Ipp32s FieldPOffset[2] = {0,0};
        Ipp32s posy;



        if ((OppositePadding)&&(!fieldPrediction))
        {
            if ((OppositePadding)&&(!fieldPrediction))
            {
                if (paddingTop)
                {
                    if ((position.y - 1) % 2)
                    {
                        FieldPOffset[0] = 1;
                        FieldPOffset[1] = 0;
                    }
                    else
                    {
                        FieldPOffset[0] = 0;
                        FieldPOffset[1] = 1;
                    }

                }
                else if (paddingBottom)
                {
                    if ((position.y - 1) % 2)
                    {
                        FieldPOffset[0] = 0;
                        FieldPOffset[1] = -1;
                    }
                    else
                    {
                        FieldPOffset[0] = -1;
                        FieldPOffset[1] = 0;
                    }
                }

            }

        }

        // Compare with paddingRight case !!!!
        if (paddingLeft)
        {
            for (int nfield = 0; nfield < 2; nfield ++)
            {
                for (int i = nfield; i < interpolateInfo->sizeBlock.height + 3; i+=2)
                {
                    posy = position.y + i - 1;
                    if (GetEdgeValue(interpolateInfo->sizeFrame.height >> SCoef, posy))
                        posy += FieldPOffset[nfield];

                    temp_block[i*temp_block_step + interpolateInfo->sizeBlock.width + 3] = (pLUT [nfield])?
                        pLUT [nfield][interpolateInfo->pSrc[0][RefBlockStep * posy]]:
                    interpolateInfo->pSrc[0][RefBlockStep * posy];
                }

            }
            paddingLeft = (paddingLeft != 0)?(interpolateInfo->sizeBlock.width + 3):paddingLeft;
        }
        if (paddingRight)
        {
            for (int nfield = 0; nfield < 2; nfield ++)
            {
                for (int i = nfield; i < interpolateInfo->sizeBlock.height + 3; i+=2)
                {
                    posy = position.y + i - 1;
                    if (GetEdgeValue(interpolateInfo->sizeFrame.height >> SCoef, posy))
                        posy += FieldPOffset[nfield];

                    temp_block[i*temp_block_step] = (pLUT [nfield])?
                        pLUT [nfield][interpolateInfo->pSrc[0][RefBlockStep * posy + interpolateInfo->sizeFrame.width - 1]]:
                    interpolateInfo->pSrc[0][RefBlockStep * posy + interpolateInfo->sizeFrame.width - 1];
                }

            }
            paddingRight = (paddingRight != 0)?(interpolateInfo->sizeBlock.width + 2):paddingRight;
        }
    }

    // prepare dst
    p_temp_block_data_pointer += paddingTop * temp_block_step + paddingLeft;
    {
         // copy block
        for (int nfield = 0; nfield < 2; nfield ++)
        {
            for (int i = nfield; i < temp_block_size.height; i+=2)
            {
                for (int j = 0; j < temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUT [nfield])?
                        pLUT[nfield][pRefBlock[i*RefBlockStep + j]]:
                    pRefBlock[i*RefBlockStep + j];
                }
            }
        }
    }

    if ((!OppositePadding)||(fieldPrediction))
    {
        if (!OppositePadding)
        {
            // interlace padding. Field prediction
            // top
            for (int i = -paddingTop; i < 0; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {

                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUT[0])?
                        pLUT[0][interpolateInfo->pSrc[0][position.x + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]; //!!! - isPredBottom*interpolateInfo->srcStep]; ///in case of isPredBottom we should use th second string
                }
            }
            // bottom
            for (int i = 0; i < paddingBottom; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[1])?
                        pLUT[1][interpolateInfo->pSrc[0][position.x + ((interpolateInfo->sizeFrame.height >> SCoef) - 1)*RefBlockStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + ((interpolateInfo->sizeFrame.height >> SCoef) - 1)*RefBlockStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep];
                }
            }
        }
        else
        {
            // progressive padding. Field prediction
            // top
            for (int i = -paddingTop; i < 0; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {

                    p_temp_block_data_pointer[i*temp_block_step + j] = (pLUTTop)?
                        pLUTTop[interpolateInfo->pSrc[0][position.x + paddingLeft +j -left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + paddingLeft +j -left - isPredBottom*interpolateInfo->srcStep];
                }
            }
            // bottom
            for (int i = 0; i < paddingBottom; i ++)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUTBottom)?
                        pLUTBottom[interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - 1)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - 1)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*interpolateInfo->srcStep];
                }
            }
        }
    }
    else
    {

        // Field padding. Progressive prediction
        if (paddingTop)
        {
        // top
        for (int i = 2; i <= paddingTop; i +=2)
        {
            for (int j = 0; j < temp_block_size.width; j++)
            {
                p_temp_block_data_pointer[-i*temp_block_step + j] = (pLUT[0])?
                    pLUT[0][interpolateInfo->pSrc[0][position.x + paddingLeft + j +TopFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep]]:
                interpolateInfo->pSrc[0][position.x + paddingLeft + j + TopFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep];
            }
        }
        for (int i = 1; i <= paddingTop; i +=2)
        {
            for (int j = 0; j < temp_block_size.width; j++)
            {
                p_temp_block_data_pointer[-i*temp_block_step + j] = (pLUT[1])?
                    pLUT[1][interpolateInfo->pSrc[0][position.x + paddingLeft +j + BottomFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep]]:
                interpolateInfo->pSrc[0][position.x + paddingLeft +j + BottomFieldPOffsetTP*interpolateInfo->srcStep - left - isPredBottom*RefBlockStep];
            }
        }
        }
        if (paddingBottom)
        {
            if (paddingBottom % 2)
            {
                const Ipp8u* pTemp;
                pTemp = pLUT[0];
                pLUT[0] = pLUT[1];
                pLUT[1] = pTemp;
            }
            // bottom
            for (int i = 0; i < paddingBottom; i +=2)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[1])?
                        pLUT[1][interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - TopFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j- left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - TopFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j- left - isPredBottom*RefBlockStep];
                }
            }
            for (int i = 1; i < paddingBottom; i +=2)
            {
                for (int j = 0; j <temp_block_size.width; j++)
                {
                    p_temp_block_data_pointer[(temp_block_size.height+i)*temp_block_step + j] = (pLUT[0])?
                        pLUT[0][interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - BottomFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*RefBlockStep]]:
                    interpolateInfo->pSrc[0][position.x + (interpolateInfo->sizeFrame.height - BottomFieldPOffsetBP)*interpolateInfo->srcStep + paddingLeft +j - left - isPredBottom*RefBlockStep];
                }
            }
        }
    }

    for (int i = 0; i < paddingLeft; i ++)
    {
        for (int j = 0; j < interpolateInfo->sizeBlock.height + 3; j++)
        {
            temp_block [i+ j*temp_block_step ] = temp_block[paddingLeft+ j*temp_block_step];
        }
    }
    for (int i = 1; i <=paddingRight; i ++)
    {
        for (int j = 0; j < interpolateInfo->sizeBlock.height + 3; j++)
        {
            temp_block [interpolateInfo->sizeBlock.width + 3 - i + j*temp_block_step + step] =
                temp_block[ interpolateInfo->sizeBlock.width + 3 - paddingRight  - 1 + j*temp_block_step + step];
        }
    }
    // prapere data for interpolation call
    IppVCInterpolate_8u inter_struct;
    inter_struct.srcStep = 19;
    inter_struct.pSrc = temp_block + 1 + inter_struct.srcStep;
    inter_struct.pDst = interpolateInfo->pDst[0];
    inter_struct.dstStep = interpolateInfo->dstStep;
    inter_struct.dx = interpolateInfo->pointVector.x;
    inter_struct.dy = interpolateInfo->pointVector.y;
    inter_struct.roundControl = RoundControl;
    inter_struct.roiSize.width = interpolateInfo->sizeBlock.width;
    inter_struct.roiSize.height = interpolateInfo->sizeBlock.height;
    return _own_ippiInterpolateQPBilinearIC_VC1_8u_C1R(&inter_struct);
}



void CalculateIntraFlag(VC1Context* pContext)
{
    Ipp8u i;
    pContext->m_pCurrMB->IntraFlag=0;

    for (i = 0; i < VC1_NUM_OF_BLOCKS; i++)
    {
        if(pContext->m_pCurrMB->m_pBlocks[i].blkType & VC1_BLK_INTRA)
        {
            pContext->m_pCurrMB->IntraFlag=(1<<i)|pContext->m_pCurrMB->IntraFlag;
        }
    }
}
#endif //UMC_ENABLE_VC1_VIDEO_DECODER
